#include "ui_screen.h"
#include <stdio.h>
#include <string.h>
#include "SEGGER_RTT.h"
#include "crc16.h"
#include "motor_ctrl.h"
#include "fiber_optic.h"
#include "param.h"
#include "app.h"
#include "ulog.h"

static void ui_screen_sned_feed_key(uint32_t num);

unsigned char buff[RING_BUFF_SIZE] = {0};
ui_screen_t ui_screen = {
    .assembly.cmd_rest_state = 0,
};

static uint8_t ui_screen_recv_lock(uint8_t* buff, uint8_t len); //锁屏,暂时不用
static uint8_t ui_screen_recv_offset(uint8_t* buff, uint8_t len);//更新offset值
static uint8_t ui_screen_recv_cmd_speed(uint8_t* buff, uint8_t len);//更新速度档位
static uint8_t ui_screen_recv_produce_num(uint8_t* buff, uint8_t len);//更新生产数量,暂时不用
static uint8_t ui_screen_recv_rest(uint8_t* buff, uint8_t len);//更新按键值->复位
static uint8_t ui_screen_recv_manual_automatic(uint8_t* buff, uint8_t len);//更新按键值->手自动状态
static uint8_t ui_screen_recv_feed(uint8_t* buff, uint8_t len);//更新按键值->进料状态
//static uint8_t ui_screen_recv_system_state(uint8_t* buff, uint8_t len);//更新按键值->系统复位
static void ui_screen_sned_release_button(uint32_t num);


typedef uint8_t (*ui_screen_function)(uint8_t* buff, uint8_t len);
ui_screen_function list_cmd_function[7] = {
    ui_screen_recv_lock,
    ui_screen_recv_offset,
    ui_screen_recv_cmd_speed,
    ui_screen_recv_produce_num,
    ui_screen_recv_rest,
    ui_screen_recv_manual_automatic,
    ui_screen_recv_feed,
//    ui_screen_recv_system_state,
};

///////////////////////////////////////////////////////////////////////////////////////
//                 以下是接收数据处理
///////////////////////////////////////////////////////////////////////////////////////
/**
*   锁定屏幕(暂时不用)
*/
static uint8_t ui_screen_recv_lock(uint8_t* buff, uint8_t len)
{
    ui_screen.assembly.state = buff[0];
    return 0;
}

/**
*   更新offset值
*/
static uint8_t ui_screen_recv_offset(uint8_t* buff, uint8_t len)
{
    motor_ctrl_t* motor_ctrl = motor_ctrl_dev();
    uint32_t temp = buff[3];

    /* 自动模式下,禁止更新offset值 */
    if(motor_ctrl->manual_automatic == MOTOR_CTRL_AUTOMATIC)
    {
        return 0;
    }
    //memcpy((uint8_t*)(&temp), buff, 4);

    if(temp == 0x00) /* 慢增加 */
    {
        if(motor_ctrl->offset_cmd < MOTOR_OFFSET_MAX)
        {
            motor_ctrl->offset_cmd++;
            param_save();
        }
        ui_screen_sned_offset(motor_ctrl->offset_cmd); /* 偏移量 */
    }
    else if(temp == 0x01) /* 快增加 */
    {
        if(motor_ctrl->offset_cmd < (MOTOR_OFFSET_MAX - 10))
        {
            motor_ctrl->offset_cmd = motor_ctrl->offset_cmd + 10;
            param_save();
        }
        else
        {
            motor_ctrl->offset_cmd = MOTOR_OFFSET_MAX;
            param_save();
        }
        ui_screen_sned_offset(motor_ctrl->offset_cmd); /* 偏移量 */
    }
    else if(temp == 0x10) /* 慢减少 */
    {
        if(motor_ctrl->offset_cmd > 0)
        {
            motor_ctrl->offset_cmd--;
            param_save();
        }
        ui_screen_sned_offset(motor_ctrl->offset_cmd); /* 偏移量 */
    }
    else if(temp == 0x20) /* 快减少 */
    {
        if(motor_ctrl->offset_cmd > 10)
        {
            motor_ctrl->offset_cmd = motor_ctrl->offset_cmd - 10;
            param_save();
        }
        else
        {
            motor_ctrl->offset_cmd = 0;
            param_save();
        }
        ui_screen_sned_offset(motor_ctrl->offset_cmd); /* 偏移量 */
    }
    else if((temp == 0x30) || (temp == 0x02)) /* 松开减少按键 */
    {
        ui_screen_sned_release_button(1);
    }

    #if (LOG_OUTPUT_EN == 1)
    SEGGER_RTT_printf(0, "ui [%d] ; screen offset = %d \r\n", temp, motor_ctrl->offset_cmd);
    #endif
    return 0;
}

/**
*   更新速度档位
*/
static uint8_t ui_screen_recv_cmd_speed(uint8_t* buff, uint8_t len)
{
    motor_ctrl_t* motor_ctrl = motor_ctrl_dev();
    uint16_t temp = 0;
    
    /* 自动模式下,禁止更新速度档位 */
    if(motor_ctrl->manual_automatic == MOTOR_CTRL_AUTOMATIC)
    {
        return 0;
    }

    memcpy(&temp, buff, 2);
    if(temp == 0) /* 增加 按键响应 */
    {
        if(motor_ctrl->speed_ratio_cmd < MOTOR_SPEED_MIN)
        {
            motor_ctrl->speed_ratio_cmd++;
            param_save();
        }
    }
    else /* 减少 按键响应 */
    {
        if(motor_ctrl->speed_ratio_cmd > MOTOR_SPEED_MAX)
        {
            motor_ctrl->speed_ratio_cmd--;
            param_save();
        }
    }
    ui_screen_sned_speed(motor_ctrl->speed_ratio_cmd);  /* 回发数据 */
    #if (LOG_OUTPUT_EN == 1)
    SEGGER_RTT_printf(0, "ui screen speed = %d \r\n", motor_ctrl->speed_ratio_cmd);
    #endif

    return 0;
}

/**
*   更新生产数量
*/
static uint8_t ui_screen_recv_produce_num(uint8_t* buff, uint8_t len)
{
    return 0;
}

/**
*   更新按键值->复位
*/
static uint8_t ui_screen_recv_rest(uint8_t* buff, uint8_t len)
{
    motor_ctrl_t* motor_ctrl = motor_ctrl_dev();

    app_set_system_status(APP_SYSTEM_CONFIG);
    motor_ctrl->manual_automatic = MOTOR_CTRL_MATNUAL;
    motor_ctrl->fault_type = 0x0000;
    #if (LOG_OUTPUT_EN == 1)
    SEGGER_RTT_printf(0, "ui ui_screen_recv_rest\r\n");
    #endif
    ui_screen_sned_fault_type(MOTOR_FAULT_DEF);

    return 0;
}

/**
*   更新按键值->手自动状态
*/
static uint8_t ui_screen_recv_manual_automatic(uint8_t* buff, uint8_t len)
{
    motor_ctrl_t* motor_ctrl = motor_ctrl_dev();
    /* 
        1.正常停车
        2.超时停车,才能切换状态
    */
    uint8_t sys_sta = app_get_system_status();
    if(sys_sta != APP_SYSTEM_OVER_TIME_STOP)
    {
        motor_ctrl->manual_automatic = buff[0];
        if(motor_ctrl->manual_automatic >= 1)
        {
            motor_ctrl->manual_automatic = 1;
            app_set_system_status(APP_SYSTEM_CONFIG);
        }
        #if (LOG_OUTPUT_EN == 1)
        SEGGER_RTT_printf(0, "ui manual_automatic = %d \r\n", motor_ctrl->manual_automatic);
        #endif
        ui_screen_sned_run_mode(1);
    }

    return 0;
}

/**
*   更新按键值->进料状态
*/
static uint8_t ui_screen_recv_feed(uint8_t* buff, uint8_t len)
{
    motor_ctrl_t* motor_ctrl = motor_ctrl_dev();
    if(motor_ctrl->manual_automatic == MOTOR_CTRL_AUTOMATIC)
    {
        return 0;
    }
    if(buff[0] == 0x00) /* 进料*/
    {
        motor_ctrl_running(2, 1, 100, 5000);
        motor_ctrl->feed_state = 1;
        ui_screen.key_over_time = main_get_system_times();
    }
    if(buff[0] == 0x01) /* 停止进料*/
    {
        motor_ctrl->feed_state = 0;
        ui_screen_sned_feed_key(1);
    }
    #if (LOG_OUTPUT_EN == 1)
    SEGGER_RTT_printf(0, "ui feed_state = %d \r\n", motor_ctrl->feed_state);
    #endif
    return 0;
}

/**
*   更新按键值->系统复位
*/
//static uint8_t ui_screen_recv_system_state(uint8_t* buff, uint8_t len)
//{
//    return 0;
//}
///////////////////////////////////////////////////////////////////////////////////////
//                 以下是给屏幕更新数据
///////////////////////////////////////////////////////////////////////////////////////

/**
 * 给屏幕发送结束符
*/
static void ui_screen_sned_end(void)
{
    uint8_t buff[3] = {0xff,0xff,0xff};
    bsp_usart3_send_buffer(buff, 3);
}

/**
 * 发送生产数量
*/
void ui_screen_sned_production_quantity(uint32_t num)
{
    char strl[32] = {0};
    snprintf(strl, 32, "main.n2.val=%d", num);
    bsp_usart3_send_buffer((uint8_t*)strl, strlen(strl));

    ui_screen_sned_end();
}

/**
 * 发送offset
*/
void ui_screen_sned_offset(uint32_t num)
{
    char strl[32] = {0};
    snprintf(strl, 32, "main.n0.val=%d", num);
    bsp_usart3_send_buffer((uint8_t*)strl, strlen(strl));

    ui_screen_sned_end();
}

/**
 * 发送speed
*/
void ui_screen_sned_speed(uint32_t num)
{
    char strl[32] = {0};
    snprintf(strl, 32, "main.n1.val=%d", num);
    bsp_usart3_send_buffer((uint8_t*)strl, strlen(strl));

    ui_screen_sned_end();
}

/**
 * 发送手动/自动模式
*/
void ui_screen_sned_run_mode(uint32_t num)
{
    char strl[32] = {0};
    snprintf(strl, 32, "main.n2.val=%d", num);
    bsp_usart3_send_buffer((uint8_t*)strl, strlen(strl));
    ui_screen_sned_end();
}

/**
 * 发送进料释放
*/
static void ui_screen_sned_feed_key(uint32_t num)
{
    char strl[32] = {0};
    snprintf(strl, 32, "goods=%d", num);
    bsp_usart3_send_buffer((uint8_t*)strl, strlen(strl));
    ui_screen_sned_end();
}

/**
 * 上报故障信息
*/
void ui_screen_sned_fault_type(uint32_t num)
{
    char strl[32] = {0};
    snprintf(strl, 32, "error=%d", num);
    bsp_usart3_send_buffer((uint8_t*)strl, strlen(strl));
    ui_screen_sned_end();
}

/**
 * 释放按键
*/
void ui_screen_sned_release_button(uint32_t num)
{
    char strl[32] = {0};
    snprintf(strl, 32, "offset=%d", num);
    bsp_usart3_send_buffer((uint8_t*)strl, strlen(strl));
    ui_screen_sned_end();
}

///////////////////////////////////////////////////////////////////////////////////////
//                 以下是数据解析
///////////////////////////////////////////////////////////////////////////////////////
/**
*   按照单个字节解析接收数据
*/
#if 0
static uint8_t ui_screen_calculate_sum8(uint8_t* buff, uint8_t len)
{
    uint8_t sum8 = 0;
    for (uint8_t i = 0; i < len; i++)
    {
        sum8 = sum8 + buff[i];
    }
    return sum8;
}
#endif
/**
*   按照单个字节解析接收数据
*/
static void ui_screen_receive_analysis(uint8_t byte)
{
    #define FRAME_HEADER_1 0x55
    #define FRAME_HEADER_2 0xaa

    static uint8_t number = 0;
    static uint8_t pos = 0;
    uint16_t cal_crc = 0;

    LAB_ANALYSIS:
    switch (number)
    {
        case 0:  /* 找帧头1 */
        if(FRAME_HEADER_1 == byte)
        {
            number = 1;
        } 
        break;
        case 1: /* 找帧头2 */
        if(FRAME_HEADER_2 == byte)
        {
            number = 2;
            pos = 0;
        }
        else
        {
            number = 0;
            goto LAB_ANALYSIS;
        }
        break;
        case 2: /* 获取长度 */
            ui_screen.size = byte;
            ui_screen.buff[pos] = byte;
            pos = 1;
            number = 3;
        break;
        case 3: /* 获取类型 */
            ui_screen.cmd_id = byte;
            ui_screen.buff[pos] = byte;
            pos = 2;
            number = 4;
        break;
        case 4: /* 获取数据 */
            ui_screen.buff[pos] = byte;
            if((++pos > (ui_screen.size + 2)) || (pos >= FRAME_SIZE)) /* +2是为了获取校验 */
            {
                uint16_t recv_crc = (ui_screen.buff[ui_screen.size + 1] << 8) | byte;
                cal_crc = crc_modbus16_check((uint8_t*)(&ui_screen.buff), (pos - 2));
                if(cal_crc == recv_crc)
                {
                    list_cmd_function[ui_screen.cmd_id](&ui_screen.buff[2], (ui_screen.size - 1));
                }
                number = 0;
            }
        break;
    default:
        break;
    }
}

/**
*   外部调用设备接口 
*/
ui_screen_t* ui_screen_dev(void)
{
    return &ui_screen;
}

/**
 * 注册UI设备
*/
void ui_screen_init(void)
{
    ring_buf_init(&(ui_screen.ring_buff), (unsigned char*)(buff), RING_BUFF_SIZE);
} 

/* UI界面接收数据处理 */
void ui_screen_recv_handle(void)
{
    uint16_t len = ring_buf_len(&ui_screen.ring_buff);

    if(len > RING_BUFF_SIZE)
    {
        ring_buf_clr(&ui_screen.ring_buff);
        return;
    }
    if(len != 0)
    {
        for(uint8_t i = 0; i < len; i++)
        {
            unsigned char byte = 0;
            while (ui_screen.ring_buff.lock == 1);
            ring_buf_get(&ui_screen.ring_buff, &byte, 1);

            ui_screen_receive_analysis(byte);
        }
    }
}
